#include "grpc_utils.h"

#include <grpcpp/generic/generic_stub.h>

using google::protobuf::Descriptor;
using google::protobuf::DescriptorPool;
using google::protobuf::DynamicMessageFactory;
using google::protobuf::FileDescriptorProto;
using google::protobuf::Message;
using google::protobuf::MethodDescriptor;
using google::protobuf::ServiceDescriptor;
// using grpc::reflection::v1alpha::ServerReflection;
// using grpc::reflection::v1alpha::ServerReflectionRequest;
// using grpc::reflection::v1alpha::ServerReflectionResponse;

// GrpcClientReflection::GrpcClientReflection(std::string server_url) {
//   channel_ =
//       grpc::CreateChannel(server_url, grpc::InsecureChannelCredentials());
//   if (!channel_) {
//     LOG(FATAL) << "grpc::CreateChannel() failed: " << server_url;
//   }
//   stub_ = ServerReflection::NewStub(channel_);
//   if (!stub_) {
//     LOG(FATAL) << "grpc::NewStub() failed: " << server_url;
//   }
//   init();
// }

// GrpcClientReflection::~GrpcClientReflection() {}

// bool GrpcClientReflection::checkConnect(int timeout_ms /*= 1000*/) {
//   auto deadline =
//       std::chrono::system_clock::now() + std::chrono::milliseconds(timeout_ms);
//   if (channel_->WaitForConnected(deadline)) {
//     LOG(INFO) << "connect checked";
//     return true;
//   } else {
//     LOG(ERROR) << "connect failed";
//     return false;
//   }
// }

// void GrpcClientReflection::init() {
//   while (true) {
//     if (!checkConnect()) {
//       LOG(ERROR) << "checkConnect() failed";
//       continue;
//     }
//     LOG(WARNING) << "checkConnect() finish";
//     std::vector<std::string> servers;
//     if (!listServices(servers)) {
//       LOG(ERROR) << "listServices() failed";
//       continue;
//     }
//     LOG(WARNING) << "listServices() finish";
//     if (!updateReflInfo(servers, refl_info_)) {
//       LOG(ERROR) << "updateReflInfo() failed";
//       continue;
//     }
//     LOG(WARNING) << "updateReflInfo() finish";
//     print(refl_info_);
//     return;
//   }
// }

// bool GrpcClientReflection::updateReflInfo(
//     const std::vector<std::string>& servers, ReflInfo& refl_info) {
//   refl_info.desc_pool = std::make_shared<DescriptorPool>();
//   for (const auto& server : servers) {
//     if (!fetchProtoInfo(server, *refl_info.desc_pool)) {
//       LOG(ERROR) << "fetchProtoInfo() failed: " << server;
//       return false;
//     }
//   }

//   for (const auto& server : servers) {
//     // init server
//     const ServiceDescriptor* service_desc =
//         refl_info.desc_pool->FindServiceByName(server);
//     if (!service_desc) {
//       LOG(ERROR) << "Service not found: " << server;
//       return false;
//     }
//     refl_info.servers[server].service_desc = service_desc;
//     // init method
//     for (int i = 0; i < service_desc->method_count(); ++i) {
//       const MethodDescriptor* method = service_desc->method(i);
//       const Descriptor* req_desc = method->input_type();
//       const Descriptor* res_desc = method->output_type();
//       std::string method_name = method->name();
//       refl_info.servers[server].methods[method_name].method_desc = method;
//       refl_info.servers[server].methods[method_name].req_desc = req_desc;
//       refl_info.servers[server].methods[method_name].res_desc = res_desc;
//     }
//   }

//   return true;
// }

// bool GrpcClientReflection::listServices(std::vector<std::string>& _servers) {
//   std::vector<std::string> servers;
//   if (!checkConnect()) {
//     LOG(ERROR) << "checkConnect() failed";
//     return false;
//   }

//   grpc::ClientContext context;
//   auto stream = stub_->ServerReflectionInfo(&context);
//   if (!stream) {
//     LOG(ERROR) << "stub_->ServerReflectionInfo() failed";
//     return false;
//   }

//   ServerReflectionRequest request;
//   request.set_list_services("");
//   if (!stream->Write(request)) {
//     LOG(ERROR) << "stream->Write() failed";
//     return false;
//   }
//   if (!stream->WritesDone()) {
//     LOG(ERROR) << "stream->WritesDone() failed";
//     return false;
//   }

//   ServerReflectionResponse response;
//   LOG(INFO) << "available server: ";
//   while (stream->Read(&response)) {
//     for (const auto& service : response.list_services_response().service()) {
//       servers.push_back(service.name());
//       LOG(INFO) << "serser: " << service.name();
//     }
//   }

//   grpc::Status status = stream->Finish();
//   if (!status.ok()) {
//     LOG(ERROR) << "Failed to list services: " << status.error_message();
//     return false;
//   }

//   std::swap(servers, _servers);

//   return true;
// }

// void GrpcClientReflection::fetchProtoFile(
//     const std::string& proto_name, DescriptorPool& desc_pool,
//     std::unordered_set<std::string>& loaded_files) {
//   //   std::cout << __LINE__ << std::endl;
//   grpc::ClientContext context;
//   auto stream = stub_->ServerReflectionInfo(&context);
//   ServerReflectionRequest request;
//   request.set_file_by_filename(proto_name);
//   stream->Write(request);
//   stream->WritesDone();
//   //   std::cout << __LINE__ << std::endl;

//   ServerReflectionResponse response;
//   while (stream->Read(&response)) {
//     // std::cout << __LINE__ << std::endl;
//     for (const auto& file_proto_data :
//          response.file_descriptor_response().file_descriptor_proto()) {
//       //   std::cout << __LINE__ << std::endl;
//       FileDescriptorProto file_proto;
//       if (!file_proto.ParseFromString(file_proto_data)) {
//         std::cerr << "Failed to parse FileDescriptorProto" << std::endl;
//         continue;
//       }

//       if (loaded_files.count(file_proto.name()) > 0) {
//         continue;
//       }
//       //   std::cout << __LINE__ << std::endl;

//       LOG(INFO) << "Loading dependent proto file: " << file_proto.name();
//       loaded_files.insert(file_proto.name());
//       desc_pool.BuildFile(file_proto);
//       //   std::cout << __LINE__ << std::endl;

//       for (const auto& dependency : file_proto.dependency()) {
//         if (loaded_files.count(dependency) == 0) {
//           fetchProtoFile(dependency, desc_pool, loaded_files);
//           //   std::cout << __LINE__ << std::endl;
//         }
//         // std::cout << __LINE__ << std::endl;
//       }
//       //   std::cout << __LINE__ << std::endl;
//     }
//     // std::cout << __LINE__ << std::endl;
//   }
// }

// bool GrpcClientReflection::fetchProtoInfo(const std::string& service_name,
//                                           DescriptorPool& desc_pool) {
//   LOG(INFO) << "Fetching proto info for service: " << service_name;

//   grpc::ClientContext context;
//   auto stream = stub_->ServerReflectionInfo(&context);

//   // 请求服务的 `.proto` 信息
//   ServerReflectionRequest request;
//   request.set_file_containing_symbol(service_name);
//   stream->Write(request);
//   stream->WritesDone();

//   ServerReflectionResponse response;
//   std::unordered_set<std::string> loaded_files;

//   // std::cout << __LINE__ << std::endl;

//   // 读取服务器返回的 `.proto` 文件
//   while (stream->Read(&response)) {
//     // std::cout << __LINE__ << std::endl;
//     if (response.has_error_response()) {
//       std::cerr << "Reflection error: "
//                 << response.error_response().error_message() << std::endl;
//       return false;
//     }
//     // std::cout << __LINE__ << std::endl;

//     for (const auto& file_proto_data :
//          response.file_descriptor_response().file_descriptor_proto()) {
//       // std::cout << "file_proto_data: " << file_proto_data << std::endl;
//       FileDescriptorProto file_proto;
//       if (!file_proto.ParseFromString(file_proto_data)) {
//         std::cerr << "Failed to parse FileDescriptorProto" << std::endl;
//         return false;
//       }

//       // 递归加载 `import` 依赖
//       // std::cout << __LINE__ << std::endl;
//       for (const auto& dependency : file_proto.dependency()) {
//         // std::cout << __LINE__ << std::endl;
//         if (loaded_files.count(dependency) == 0) {
//           // std::cout << __LINE__ << std::endl;
//           LOG(INFO) << "Loading proto file dependency: " << file_proto.name()
//                     << ":" << dependency;
//           fetchProtoFile(dependency, desc_pool, loaded_files);
//         }
//         // std::cout << __LINE__ << std::endl;
//       }
//       // std::cout << __LINE__ << std::endl;
//       if (loaded_files.count(file_proto.name()) == 0) {
//         LOG(INFO) << "Loading proto file: " << file_proto.name();
//         loaded_files.insert(file_proto.name());
//         desc_pool.BuildFile(file_proto);
//       }
//     }
//     // std::cout << __LINE__ << std::endl;
//   }
//   // std::cout << __LINE__ << std::endl;

//   grpc::Status status = stream->Finish();
//   // std::cout << __LINE__ << std::endl;
//   // std::cout << status.ok() << std::endl;
//   return status.ok();
// }

// void GrpcClientReflection::print(const ReflInfo& refl_info) {
//   for (auto server_info : refl_info.servers) {
//     LOG(INFO) << "server name: " << server_info.first;
//     for (auto method : server_info.second.methods) {
//       LOG(INFO) << "\tmethod: " << method.second.method_desc->full_name();
//       LOG(INFO) << "\t\t"
//                 << "input: " << method.second.req_desc->full_name();
//       LOG(INFO) << "\t\t"
//                 << "output: " << method.second.res_desc->full_name();
//     }
//   }
// }

// const google::protobuf::MethodDescriptor* GrpcClientReflection::getMethodDesc(
//     std::string service_name, std::string method_name) {
//   auto it_server = refl_info_.servers.find(service_name);
//   if (it_server == refl_info_.servers.end()) {
//     LOG(ERROR) << "unknow server: " << service_name;
//     return nullptr;
//   }
//   auto it_method = it_server->second.methods.find(method_name);
//   if (it_method == it_server->second.methods.end()) {
//     LOG(ERROR) << "unknow method: " << method_name;
//     return nullptr;
//   }
//   return it_method->second.method_desc;
// }

// std::shared_ptr<google::protobuf::Message> GrpcClientReflection::createRequest(
//     std::string service_name, std::string method_name) {
//   LOG(INFO) << __LINE__;
//   const MethodDescriptor* method_desc =
//       getMethodDesc(service_name, method_name);
//   if (!method_desc) {
//     LOG(ERROR) << "getMethodDesc() failed";
//     return nullptr;
//   }
//   LOG(INFO) << __LINE__;
//   const Descriptor* req_desc = method_desc->input_type();

//   std::shared_ptr<Message> req_msg = std::shared_ptr<Message>(
//       refl_info_.message_factory.GetPrototype(req_desc)->New());
//   if (!req_msg) {
//     LOG(ERROR) << "Failed to create request message";
//     return nullptr;
//   }
//   // LOG(INFO) << __LINE__;

//   // req_msg->GetReflection()->SetString(req_msg.get(),
//   //                                     req_desc->FindFieldByName("aaa"),
//   //                                     "100");
//   // LOG(INFO) << __LINE__ << " : " << protoMessageToJson(*req_msg);

//   return req_msg;
// }

// std::shared_ptr<google::protobuf::Message> GrpcClientReflection::grpcCall(
//     std::string service_name, std::string method_name,
//     const google::protobuf::Message& req_msg) {
//   const MethodDescriptor* method_desc =
//       getMethodDesc(service_name, method_name);
//   if (!method_desc) {
//     LOG(ERROR) << "getMethodDesc() failed";
//     return nullptr;
//   }

//   grpc::GenericStub stub(channel_);
//   grpc::ClientContext context;
//   grpc::CompletionQueue cq;
//   grpc::Status status;
//   grpc::ByteBuffer request_buffer;

//   std::string request_serialized;
//   if (!req_msg.SerializeToString(&request_serialized)) {
//     LOG(ERROR) << "Failed to serialize request message";
//     return nullptr;
//   }
//   grpc::Slice request_slice(request_serialized);
//   request_buffer = grpc::ByteBuffer(&request_slice, 1);

//   std::unique_ptr<grpc::GenericClientAsyncResponseReader> rpc(
//       stub.PrepareUnaryCall(&context, "/" + service_name + "/" + method_name,
//                             request_buffer, &cq));
//   if (!rpc) {
//     LOG(ERROR) << "Failed to prepare RPC call.";
//     return nullptr;
//   }
//   rpc->StartCall();
//   grpc::ByteBuffer response_buffer;
//   rpc->Finish(&response_buffer, &status, (void*)1);
//   void* got_tag;
//   bool ok = false;
//   if (!cq.Next(&got_tag, &ok)) {
//     LOG(ERROR) << "cq.Next() failed";
//     return nullptr;
//   }
//   if (!ok || got_tag != (void*)1 || !status.ok()) {
//     LOG(ERROR) << "RPC failed: " << status.error_message();
//     return nullptr;
//   }

//   std::vector<grpc::Slice> slices;
//   status = response_buffer.Dump(&slices);
//   if (!status.ok()) {
//     LOG(ERROR) << "response_buffer.Dump() failed";
//     return nullptr;
//   }
//   std::string response_serialized;
//   for (const auto& slice : slices) {
//     response_serialized.append(reinterpret_cast<const char*>(slice.begin()),
//                                slice.size());
//   }
//   const Descriptor* res_desc = method_desc->output_type();
//   CHECK(res_desc);
//   std::shared_ptr<google::protobuf::Message> res_msg(
//       refl_info_.message_factory.GetPrototype(res_desc)->New());
//   CHECK(res_msg);
//   if (!res_msg->ParseFromString(response_serialized)) {
//     LOG(ERROR) << "Failed to parse response message";
//     return nullptr;
//   }

//   return res_msg;
// }

// /////////////////////////////
// // GrpcClientReflectionEx
// /////////////////////////////
// GrpcClientReflectionEx::GrpcClientReflectionEx(std::string server_url) {
//   server_url_ = server_url;
//   grpc::ChannelArguments args;
//   args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000);
//   args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 1000);
//   args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 1000);
//   channel_ = grpc::CreateCustomChannel(
//       server_url_, grpc::InsecureChannelCredentials(), args);
//   CHECK(channel_);
//   tryConnect();
//   is_running_ = true;
//   monitor_thread_ =
//       std::make_shared<std::thread>(&GrpcClientReflectionEx::monitorLoop, this);
//   CHECK(monitor_thread_);
// }

// GrpcClientReflectionEx::~GrpcClientReflectionEx() {
//   is_running_ = false;
//   monitor_thread_->join();
//   monitor_thread_.reset();
//   reset();
// }

// void GrpcClientReflectionEx::reset() {
//   message_factory_.reset();
//   descriptor_pool_.reset();
//   reflection_db_.reset();
// }

// void GrpcClientReflectionEx::tryConnect() {
//   std::lock_guard<std::mutex> lock(mtx_);
//   reset();
//   reflection_db_ =
//       std::make_shared<grpc::ProtoReflectionDescriptorDatabase>(channel_);
//   CHECK(reflection_db_);
//   descriptor_pool_ = std::make_shared<DescriptorPool>(reflection_db_.get());
//   CHECK(descriptor_pool_);
//   message_factory_ = std::make_shared<DynamicMessageFactory>();
//   CHECK(message_factory_);
//   return;
// }

// bool GrpcClientReflectionEx::waitForConnect(int timeout_ms) {
//   return channel_->WaitForConnected(std::chrono::system_clock::now() +
//                                     std::chrono::milliseconds(timeout_ms));
// }

// bool GrpcClientReflectionEx::checkConnect() {
//   std::vector<std::string> servers;
//   return listServices(servers);
//   // return  channel_->GetState(true) == GRPC_CHANNEL_READY;
// }

// void GrpcClientReflectionEx::monitorLoop() {
//   LOG(WARNING) << "ENTER GrpcClientReflectionEx::monitorLoop()";
//   while (is_running_) {
//     std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//     if (!checkConnect()) {
//       LOG(ERROR) << "checkConnect() failed, retry connect";
//       tryConnect();
//     } else {
//       LOG_EVERY_N(INFO, 5) << "connected";
//     }
//   }
//   LOG(WARNING) << "LEAVE GrpcClientReflectionEx::monitorLoop()";
// }

// bool GrpcClientReflectionEx::listServices(std::vector<std::string>& servers) {
//   std::lock_guard<std::mutex> lock(mtx_);
//   if (!reflection_db_->GetServices(&servers)) {
//     LOG(ERROR) << "GetServices() failed";
//     return false;
//   }
//   return true;
// }

// bool GrpcClientReflectionEx::createReqRes(
//     std::string service_name, std::string method_name,
//     std::shared_ptr<google::protobuf::Message>& req_msg,
//     std::shared_ptr<google::protobuf::Message>& res_msg) {
//   std::lock_guard<std::mutex> lock(mtx_);
//   const google::protobuf::ServiceDescriptor* service_descriptor =
//       descriptor_pool_->FindServiceByName(service_name);
//   if (!service_descriptor) {
//     LOG(ERROR) << "Service not found: " << service_name;
//     return false;
//   }

//   const google::protobuf::MethodDescriptor* method_descriptor =
//       service_descriptor->FindMethodByName(method_name);
//   if (!method_descriptor) {
//     LOG(ERROR) << "Method not found: " << method_name;
//     return false;
//   }

//   const google::protobuf::Descriptor* request_descriptor =
//       method_descriptor->input_type();
//   if (!request_descriptor) {
//     LOG(ERROR) << "input_type() failed";
//     return false;
//   }
//   req_msg.reset(message_factory_->GetPrototype(request_descriptor)->New());
//   if (!req_msg) {
//     LOG(ERROR) << "Failed to create request message";
//     return false;
//   }

//   const google::protobuf::Descriptor* response_descriptor =
//       method_descriptor->output_type();
//   if (!response_descriptor) {
//     LOG(ERROR) << "output_type() failed";
//     return false;
//   }
//   res_msg.reset(message_factory_->GetPrototype(response_descriptor)->New());
//   if (!res_msg) {
//     LOG(ERROR) << "Failed to create response message";
//     return false;
//   }

//   return true;
// }

// bool GrpcClientReflectionEx::grpcCall(std::string service_name,
//                                       std::string method_name,
//                                       const google::protobuf::Message& req_msg,
//                                       google::protobuf::Message& res_msg) {
//   std::lock_guard<std::mutex> lock(mtx_);
//   std::string request_serialized;
//   if (!req_msg.SerializeToString(&request_serialized)) {
//     LOG(ERROR) << "Failed to serialize request message" << std::endl;
//     return false;
//   }
//   grpc::GenericStub stub(channel_);
//   grpc::ClientContext context;
//   grpc::CompletionQueue cq;
//   grpc::Status status;
//   grpc::ByteBuffer request_buffer;
//   grpc::Slice request_slice(request_serialized);
//   request_buffer = grpc::ByteBuffer(&request_slice, 1);
//   std::unique_ptr<grpc::GenericClientAsyncResponseReader> rpc(
//       stub.PrepareUnaryCall(&context, "/" + service_name + "/" + method_name,
//                             request_buffer, &cq));
//   if (!rpc) {
//     LOG(ERROR) << "Failed to prepare RPC call.";
//     return false;
//   }
//   rpc->StartCall();
//   grpc::ByteBuffer response_buffer;
//   rpc->Finish(&response_buffer, &status, (void*)1);
//   void* got_tag;
//   bool ok = false;
//   if (!cq.Next(&got_tag, &ok)) {
//     LOG(ERROR) << "cq.Next() failed";
//     return false;
//   }
//   if (!ok || got_tag != (void*)1 || !status.ok()) {
//     LOG(ERROR) << "RPC failed: " << status.error_message();
//     return false;
//   }
//   std::vector<grpc::Slice> slices;
//   status = response_buffer.Dump(&slices);
//   if (!status.ok()) {
//     LOG(ERROR) << "response_buffer.Dump() failed: " << status.error_message();
//     return false;
//   }
//   std::string response_serialized;
//   for (const auto& slice : slices) {
//     response_serialized.append(reinterpret_cast<const char*>(slice.begin()),
//                                slice.size());
//   }

//   if (!res_msg.ParseFromString(response_serialized)) {
//     LOG(ERROR) << "Failed to parse response message";
//     return false;
//   }

//   return true;
// }

// google::protobuf::Message* GrpcClientReflectionEx::createReflMsg(
//     const std::string& message_name) {
//   const google::protobuf::Descriptor* descriptor =
//       descriptor_pool_->FindMessageTypeByName(message_name);
//   if (descriptor == nullptr) {
//     LOG(ERROR) << "Descriptor for message '" << message_name << "' not found!";
//     return nullptr;
//   }

//   const google::protobuf::Message* prototype =
//       message_factory_->GetPrototype(descriptor);
//   if (prototype == nullptr) {
//     LOG(ERROR) << "Prototype for message '" << message_name << "' not found!";
//     return nullptr;
//   }

//   google::protobuf::Message* message = prototype->New();
//   if (message == nullptr) {
//     LOG(ERROR) << "Failed to create message for '" << message_name << "'!";
//     return nullptr;
//   }

//   return message;
// }

// google::protobuf::Message* GrpcClientReflectionEx::mutableReflSubMsg(
//     google::protobuf::Message& msg, const std::string& field_name) {
//   const google::protobuf::Descriptor* latest_msg_desc =
//       descriptor_pool_->FindMessageTypeByName(msg.GetTypeName());
//   if (latest_msg_desc == nullptr) {
//     LOG(ERROR) << "Descriptor for message '" << msg.GetTypeName()
//                << "' not found in descriptor pool!";
//     return nullptr;
//   }

//   const google::protobuf::FieldDescriptor* field_desc =
//       latest_msg_desc->FindFieldByName(field_name);
//   if (field_desc == nullptr) {
//     LOG(ERROR) << "Field '" << field_name
//                << "' not found in latest message descriptor!";
//     return nullptr;
//   }

//   if (field_desc->type() != google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
//     LOG(ERROR) << "Field '" << field_name << "' is not a message type!";
//     return nullptr;
//   }

//   const google::protobuf::Descriptor* sub_msg_desc = field_desc->message_type();
//   if (sub_msg_desc == nullptr) {
//     LOG(ERROR) << "No message type found for field '" << field_name << "'!";
//     return nullptr;
//   }

//   const google::protobuf::Message* prototype =
//       message_factory_->GetPrototype(sub_msg_desc);
//   if (prototype == nullptr) {
//     LOG(ERROR) << "Failed to get prototype for nested message type!";
//     return nullptr;
//   }

//   const google::protobuf::Reflection* reflection = msg.GetReflection();
//   if (reflection == nullptr) {
//     LOG(ERROR) << "Reflection for message '" << msg.GetTypeName()
//                << "' not found!";
//     return nullptr;
//   }

//   google::protobuf::Message* sub_msg = prototype->New();
//   if (sub_msg == nullptr) {
//     LOG(ERROR) << "Failed to create a new instance of submessage for field '"
//                << field_name << "'!";
//     return nullptr;
//   }

//   reflection->SetAllocatedMessage(&msg, sub_msg, field_desc);
//   return sub_msg;
// }

bool getProtoEnumStr(const google::protobuf::Message &msg,
                     const std::string &field_name, std::string &field_value)
{
  // 获取字段描述符
  const google::protobuf::Descriptor *descriptor = msg.GetDescriptor();
  const google::protobuf::FieldDescriptor *field =
      descriptor->FindFieldByName(field_name);
  if (!field)
  {
    LOG(ERROR) << "Invalid field_name: " << field_name;
    return false;
  }

  if (field->type() != google::protobuf::FieldDescriptor::TYPE_ENUM)
  {
    LOG(ERROR) << "Field is not an enum: " << field_name;
    return false;
  }

  const google::protobuf::EnumDescriptor *enum_desc = field->enum_type();
  if (!enum_desc)
  {
    LOG(ERROR) << "Invalid enum descriptor for field: " << field_name;
    return false;
  }

  const google::protobuf::Reflection *reflection = msg.GetReflection();
  if (!reflection)
  {
    LOG(ERROR) << "Reflection is null for message";
    return false;
  }

  const google::protobuf::EnumValueDescriptor *enum_value_desc =
      reflection->GetEnum(msg, field);
  if (!enum_value_desc)
  {
    LOG(ERROR) << "Failed to get enum value for field: " << field_name;
    return false;
  }

  field_value = enum_value_desc->name();
  return true;
}

bool setProtoEnumStr(google::protobuf::Message &msg,
                     const std::string &field_name,
                     const std::string &field_value)
{
  // 获取字段描述符
  const google::protobuf::Descriptor *descriptor = msg.GetDescriptor();
  const google::protobuf::FieldDescriptor *field =
      descriptor->FindFieldByName(field_name);
  if (!field)
  {
    LOG(ERROR) << "Invalid field_name: " << field_name;
    return false;
  }

  // 确保字段类型是枚举
  if (field->type() != google::protobuf::FieldDescriptor::TYPE_ENUM)
  {
    LOG(ERROR) << "Field is not an enum: " << field_name;
    return false;
  }

  // 获取枚举类型描述符
  const google::protobuf::EnumDescriptor *enum_desc = field->enum_type();
  if (!enum_desc)
  {
    LOG(ERROR) << "Invalid enum descriptor for field: " << field_name;
    return false;
  }

  // 查找对应的枚举值
  const google::protobuf::EnumValueDescriptor *enum_value_desc =
      enum_desc->FindValueByName(field_value);
  if (!enum_value_desc)
  {
    LOG(ERROR) << "Invalid enum value: " << field_value
               << " for field: " << field_name;
    return false;
  }

  // 通过反射设置枚举字段的值
  const google::protobuf::Reflection *reflection = msg.GetReflection();
  if (!reflection)
  {
    LOG(ERROR) << "Reflection is null for message";
    return false;
  }

  reflection->SetEnum(&msg, field, enum_value_desc);
  return true;
}

google::protobuf::Message *mutableSubMessage(
    google::protobuf::Message &msg, const std::string &field_name)
{
  const google::protobuf::Descriptor *descriptor = msg.GetDescriptor();
  const google::protobuf::Reflection *reflection = msg.GetReflection();

  const google::protobuf::FieldDescriptor *field_desc =
      descriptor->FindFieldByName(field_name);
  if (!field_desc)
  {
    LOG(ERROR) << "Field not found: " << msg.GetTypeName() << ":" << field_name;
    return nullptr;
  }

  if (field_desc->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE)
  {
    return reflection->MutableMessage(&msg, field_desc);
  }
  else
  {
    LOG(ERROR) << "Field is not a message type: " << msg.GetTypeName() << ":"
               << field_name;
    return nullptr;
  }
}